home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Essentials / Technical.Notes / PDOS / TN.PDOS.017 < prev    next >
Encoding:
Text File  |  1989-11-09  |  33.6 KB  |  666 lines  |  [TEXT/pdos]

  1. Apple II
  2. Technical Notes
  3. _____________________________________________________________________________
  4.                                                   Developer Technical Support
  5.  
  6.  
  7. ProDOS 8
  8. #17:    Recursive ProDOS Catalog Routine
  9.  
  10. Revised by:    Dave Lyons, Keith Rollin, & Matt Deatherage      November 1989
  11. Written by:    Greg Seitz                                       December 1983
  12.  
  13. This Technical Note presents an assembly language example of a recursive 
  14. directory reading routine which is AppleShare compatible.
  15. Changes since November 1988:  The routine now ignores the file_count 
  16. field in a directory, and it properly increments ThisBlock.  More discussion 
  17. of AppleShare volumes is included.
  18. _____________________________________________________________________________
  19.  
  20. This Note presents a routine in assembly language for recursively cataloging a 
  21. ProDOS directory.  If you apply this technique to the volume directory of a 
  22. disk, it will display the name of every file stored on the disk.  The routine 
  23. displays the contents of a given directory (the volume directory in this 
  24. case), displays the contents of each subdirectory as it is encountered.
  25.  
  26. READ_BLOCK is not used, since it does not work with AppleShare servers.  READ 
  27. is used instead, since it works for AppleShare volumes as well as local disks.  
  28. Instead of using directory pointers to decide which block to read next, we 
  29. simply read the directory and display filenames as we go, until we reach a 
  30. subdirectory file.  When we reach a subdirectory, the routine saves our place, 
  31. plunges down one level of the tree structure, and catalogs the subdirectory.  
  32. You repeat the process if you find a subdirectory at the current level.  When 
  33. you reach the EOF of any directory, the routine closes the current directory 
  34. and pops back up one level, and when it reaches the EOF of the initial 
  35. directory, the routine is finished.
  36.  
  37. This routine is generally compatible with AppleShare volumes, but it is 
  38. impossible to guarantee a complete traversal of all the accessible files on an 
  39. AppleShare volume:  another user on the same volume can add or remove files or 
  40. directories at any time.  If entries are added or removed, some filenames may 
  41. be displayed twice or missed completely.  Be sure that your programs deal with 
  42. this sort of situation adequately.
  43.  
  44. We assume that AppleShare is in short naming mode (as it is by default under 
  45. ProDOS 8).  If you enable long naming mode, then illegal characters in 
  46. filenames will not be translated into question marks.  In this case, the code 
  47. would need to be modified to deal with non-ASCII characters.  Also, the 
  48. ChopName routine would need to be aware that a slash (/) character could be 
  49. contained inside the name of a directory that had been added to the pathname.  
  50. (As the code stands, such directories fail to open, but their names are still 
  51. temporarily added to the pathname.)
  52.  
  53. When the catalog routine encounters an error, it displays a brief message and 
  54. continues.  It is important not to abort on an error, since AppleShare volumes 
  55. generally contain files and folders with names that are inaccessible to 
  56. ProDOS, as well as folders that are inaccessible to your program's user (error 
  57. $4E, access error).
  58.  
  59. The code example includes a simple test of the ReadDir routine, which is the 
  60. actual recursive catalog routine.  Note that the simple test relies upon the 
  61. GETBUFR routine in BASIC.SYSTEM to allocate a buffer; therefore, as presented, 
  62. the routine requires the presence of BASIC.SYSTEM.  The actual ReadDir routine 
  63. requires nothing outside of the ProDOS 8 MLI.
  64.  
  65. ----- NEXT OBJECT FILE NAME IS CATALOG.0                     
  66. 0800:        0800    2           org   $800
  67. 0800:                3 *******************************************************
  68. 0800:                4 *
  69. 0800:                5 * Recursive ProDOS Catalog Routine
  70. 0800:                6 *
  71. 0800:                7 * by: Greg Seitz 12/83
  72. 0800:                8 *     Pete McDonald 1/86
  73. 0800:                9 *     Keith Rollin 7/88
  74. 0800:               10 *     Dave Lyons 11/89
  75. 0800:               11 *
  76. 0800:               12 * This program shows the latest "Apple Approved"
  77. 0800:               13 * method for reading a directory under ProDOS 8.
  78. 0800:               14 * READ_BLOCK is not used, since it is incompatible
  79. 0800:               15 * with AppleShare file servers.
  80. 0800:               16 *
  81. 0800:               17 * November 1989: The file_count field is no longer
  82. 0800:               18 * used (all references to ThisEntry were removed).
  83. 0800:               19 * This is because the file count can change on the fly
  84. 0800:               20 * on AppleShare volumes.  (Note that the old code was
  85. 0800:               21 * accidentally decrementing the file count when it
  86. 0800:               22 * found an entry for a deleted file, so some files
  87. 0800:               23 * could be left off the end of the list.)
  88. 0800:               24 *
  89. 0800:               25 * Also, ThisBlock now gets incremented when a chunk
  90. 0800:               26 * of data is read from a directory.  Previously, this
  91. 0800:               27 * routine could get stuck in an endless loop when
  92. 0800:               28 * a subdirectory was found outside the first block of
  93. 0800:               29 * its parent directory.
  94. 0800:               30 *
  95. 0800:               31 * Limitations:  This routine cannot reach any
  96. 0800:               32 * subdirectory whose pathname is longer than 64
  97. 0800:               33 * characters, and it will not operate correctly if
  98. 0800:               34 * any subdirectory is more than 255 blocks long
  99. 0800:               35 * (because ThisBlock is only one byte).
  100. 0800:               36 *
  101. 0800:               37 *******************************************************
  102. 0800:               38 *
  103. 0800:               39 * Equates
  104. 0800:               40 *
  105. 0800:               41 * Zero page locations
  106. 0800:               42 *
  107. 0800:        0080   43 dirName   equ   $80           ; pointer to directory name
  108. 0800:        0082   44 entPtr    equ   $82           ; ptr to current entry
  109. 0800:               45 *
  110. 0800:               46 * ProDOS command numbers
  111. 0800:               47 *
  112. 0800:        BF00   48 MLI       equ   $BF00         ; MLI entry point
  113. 0800:        00C7   49 mliGetPfx equ   $C7           ; GET_PREFIX
  114. 0800:        00C8   50 mliOpen   equ   $C8           ; Open a file command
  115. 0800:        00CA   51 mliRead   equ   $CA           ; Read a file command
  116. 0800:        00CC   52 mliClose  equ   $CC           ; Close a file command
  117. 0800:        00CE   53 mliSetMark equ  $CE           ; SET_MARK command
  118. 0800:        004C   54 EndOfFile equ   $4C           ; EndOfFile error
  119. 0800:               55 *
  120. 0800:               56 * BASIC.SYSTEM stuff
  121. 0800:               57 *
  122. 0800:        BEF5   58 GetBufr   equ   $BEF5         ; BASIC.SYSTEM get buffer routine
  123.  
  124. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 3
  125.  
  126. 0800:               59 *
  127. 0800:               60 * Offsets into the directory
  128. 0800:               61 *
  129. 0800:        0000   62 oType     equ   $0            ; offset to file type byte
  130. 0800:        0023   63 oEntLen   equ   $23           ; length of each dir. entry
  131. 0800:        0024   64 oEntBlk   equ   $24           ; entries in each block
  132. 0800:               65 *
  133. 0800:               66 * Monitor routines
  134. 0800:               67 *
  135. 0800:        FDED   68 cout      equ   $FDED         ; output a character
  136. 0800:        FD8E   69 crout     equ   $FD8E         ; output a RETURN
  137. 0800:        FDDA   70 prbyte    equ   $FDDA         ; print byte in hex
  138. 0800:        00A0   71 space     equ   $A0           ; a space character
  139. 0800:               72 *
  140. 0800:               73 *******************************************************
  141. 0800:               74 *
  142. 0800:        0800   75 Start     equ   *
  143. 0800:               76 *
  144. 0800:               77 * Simple routine to test the recursive ReadDir
  145. 0800:               78 * routine. It gets an I/O buffer for ReadDir, gets
  146. 0800:               79 * the current prefix, sets the depth of recursion
  147. 0800:               80 * to zero, and calls ReadDir to process all of the
  148. 0800:               81 * entries in the directory.
  149. 0800:               82 *
  150. 0800:A9 04          83           lda   #4            ; get an I/O buffer
  151. 0802:20 F5 BE       84           jsr   GetBufr
  152. 0805:B0 17   081E   85           bcs   exit          ; didn't get it
  153. 0807:8D D7 09       86           sta   ioBuf+1
  154. 080A:               87 *
  155. 080A:               88 * Use the current prefix for the name of the
  156. 080A:               89 * directory to display.  Note that the string we
  157. 080A:               90 * pass to ReadDir has to end with a "/", and that
  158. 080A:               91 * the result of GET_PREFIX does.
  159. 080A:               92 *
  160. 080A:20 00 BF       93           jsr   MLI
  161. 080D:C7             94           db    mliGetPfx
  162. 080E:E8 09          95           dw    GetPParms
  163. 0810:B0 0C   081E   96           bcs   exit
  164. 0812:               97 *
  165. 0812:A9 00          98           lda   #0
  166. 0814:8D CE 09       99           sta   Depth
  167. 0817:              100 *
  168. 0817:A9 EB         101           lda   #nameBuffer
  169. 0819:A2 0B         102           ldx   #<nameBuffer
  170. 081B:20 1F 08      103           jsr   ReadDir
  171. 081E:              104 *
  172. 081E:        081E  105 exit      equ   *
  173. 081E:60            106           rts
  174. 081F:              107 *
  175. 081F:              108 *******************************************************
  176. 081F:              109 *******************************************************
  177. 081F:              110 *
  178. 081F:        081F  111 ReadDir   equ   *
  179. 081F:              112 *
  180. 081F:              113 *  This is the actual recursive routine. It takes as
  181. 081F:              114 *  input a pointer to the directory name to read in
  182. 081F:              115 *  A,X (lo,hi), opens it, and starts to read the
  183. 081F:              116 *  entries. When it encounters a filename, it calls
  184.  
  185. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 4
  186.  
  187. 081F:              117 *  the routine "VisitFile". When it encounters a
  188. 081F:              118 *  directory name, it calls "VisitDir".
  189. 081F:              119 *
  190. 081F:              120 *  The directory pathname string must end with a "/"
  191. 081F:              121 *  character.
  192. 081F:              122 *
  193. 081F:              123 *******************************************************
  194. 081F:              124 *
  195. 081F:85 80         125           sta   dirName       ; save a pointer to name
  196. 0821:86 81         126           stx   dirName+1
  197. 0823:              127 *
  198. 0823:8D D4 09      128           sta   openName      ; set up OpenFile params
  199. 0826:8E D5 09      129           stx   openName+1
  200. 0829:              130 *
  201. 0829:        0829  131 ReadDir1  equ   *             ; recursive entry point
  202. 0829:20 79 08      132           jsr   OpenDir       ; open the directory as a file
  203. 082C:B0 1F   084D  133           bcs   done
  204. 082E:              134 *
  205. 082E:4C 48 08      135           jmp   nextEntry     ; jump to the end of the loop
  206. 0831:              136 *
  207. 0831:        0831  137 loop      equ   *
  208. 0831:A0 00         138           ldy   #oType        ; get type of current entry
  209. 0833:B1 82         139           lda   (entPtr),y
  210. 0835:29 F0         140           and   #$F0          ; look at 4 high bits
  211. 0837:C9 00         141           cmp   #0            ; inactive entry?
  212. 0839:F0 0D   0848  142           beq   nextEntry     ; yes - bump to next one
  213. 083B:C9 D0         143           cmp   #$D0          ; is it a directory?
  214. 083D:F0 06   0845  144           beq   ItsADir       ; yes, so call VisitDir
  215. 083F:20 B3 08      145           jsr   VisitFile     ; no, it's a file
  216. 0842:4C 48 08      146           jmp   nextEntry
  217. 0845:              147 *
  218. 0845:20 BA 08      148 ItsADir   jsr   VisitDir
  219. 0848:        0848  149 nextEntry equ   *
  220. 0848:20 77 09      150           jsr   GetNext       ; get pointer to next entry
  221. 084B:90 E4   0831  151           bcc   loop          ; Carry set means we're done
  222. 084D:        084D  152 done      equ   *             ; moved before PHA (11/89 DAL)
  223. 084D:48            153           pha                 ; save error code
  224. 084E:              154 *
  225. 084E:20 00 BF      155           jsr   MLI           ; close the directory
  226. 0851:CC            156           db    mliClose
  227. 0852:E1 09         157           dw    CloseParms
  228. 0854:              158 *
  229. 0854:68            159           pla                 ;we're expecting EndOfFile error
  230. 0855:C9 4C         160           cmp   #EndOfFile
  231. 0857:F0 1F   0878  161           beq   hitDirEnd
  232. 0859:              162 *
  233. 0859:              163 * We got an error other than EndOfFile--report the
  234. 0859:              164 * error clumsily ("ERR=$xx").
  235. 0859:              165 *
  236. 0859:48            166           pha
  237. 085A:A9 C5         167           lda   #'E'|$80
  238. 085C:20 ED FD      168           jsr   cout
  239. 085F:A9 D2         169           lda   #'R'|$80
  240. 0861:20 ED FD      170           jsr   cout
  241. 0864:20 ED FD      171           jsr   cout
  242. 0867:A9 BD         172           lda   #'='|$80
  243. 0869:20 ED FD      173           jsr   cout
  244. 086C:A9 A4         174           lda   #'$'|$80
  245.  
  246. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 5
  247.  
  248. 086E:20 ED FD      175           jsr   cout
  249. 0871:68            176           pla
  250. 0872:20 DA FD      177           jsr   prbyte
  251. 0875:20 8E FD      178           jsr   crout
  252. 0878:              179 *
  253. 0878:        0878  180 hitDirEnd equ   *
  254. 0878:60            181           rts
  255. 0879:              182 *
  256. 0879:              183 *******************************************************
  257. 0879:              184 *
  258. 0879:        0879  185 OpenDir   equ   *
  259. 0879:              186 *
  260. 0879:              187 *  Opens the directory pointed to by OpenParms
  261. 0879:              188 *  parameter block. This pointer should be init-
  262. 0879:              189 *  ialized BEFORE this routine is called. If the
  263. 0879:              190 *  file is successfully opened, the following
  264. 0879:              191 *  variables are set:
  265. 0879:              192 *
  266. 0879:              193 *     xRefNum     ; all the refnums
  267. 0879:              194 *     entryLen    ; size of directory entries
  268. 0879:              195 *     entPtr     ; pointer to current entry
  269. 0879:              196 *     ThisBEntry  ; entry number within this block
  270. 0879:              197 *     ThisBlock   ; offset (in blocks) into dir.
  271. 0879:              198 *
  272. 0879:20 00 BF      199           jsr   MLI           ; open dir as a file
  273. 087C:C8            200           db    mliOpen
  274. 087D:D3 09         201           dw    OpenParms
  275. 087F:B0 31   08B2  202           bcs   OpenDone
  276. 0881:              203 *
  277. 0881:AD D8 09      204           lda   oRefNum       ; copy the refnum return-
  278. 0884:8D DA 09      205           sta   rRefNum       ; ed by Open into the
  279. 0887:8D E2 09      206           sta   cRefNum       ; other param blocks.
  280. 088A:8D E4 09      207           sta   sRefNum
  281. 088D:              208 *
  282. 088D:20 00 BF      209           jsr   MLI           ; read the first block
  283. 0890:CA            210           db    mliRead
  284. 0891:D9 09         211           dw    ReadParms
  285. 0893:B0 1D   08B2  212           bcs   OpenDone
  286. 0895:              213 *
  287. 0895:AD 0E 0A      214           lda   buffer+oEntLen ; init 'entryLen'
  288. 0898:8D D1 09      215           sta   entryLen
  289. 089B:              216 *
  290. 089B:A9 EF         217           lda   #buffer+4     ; init ptr to first entry
  291. 089D:85 82         218           sta   entPtr
  292. 089F:A9 09         219           lda   #<buffer+4
  293. 08A1:85 83         220           sta   entPtr+1
  294. 08A3:              221 *
  295. 08A3:AD 0F 0A      222           lda   buffer+oEntblk ; init these values based on
  296. 08A6:8D CF 09      223           sta   ThisBEntry    ; values in the dir header
  297. 08A9:8D D2 09      224           sta   entPerBlk
  298. 08AC:              225 *
  299. 08AC:A9 00         226           lda   #0            ; init block offset into dir.
  300. 08AE:8D D0 09      227           sta   ThisBlock
  301. 08B1:              228 *
  302. 08B1:18            229           clc                 ; say that open was OK
  303. 08B2:              230 *
  304. 08B2:        08B2  231 OpenDone  equ   *
  305. 08B2:60            232           rts
  306.  
  307. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 6
  308.  
  309. 08B3:              233 *
  310. 08B3:              234 *******************************************************
  311. 08B3:              235 *
  312. 08B3:        08B3  236 VisitFile equ   *
  313. 08B3:              237 *
  314. 08B3:              238 * Do whatever is necessary when we encounter a
  315. 08B3:              239 * file entry in the directory. In this case, we
  316. 08B3:              240 * print the name of the file.
  317. 08B3:              241 *
  318. 08B3:20 AC 09      242           jsr   PrintEntry
  319. 08B6:20 8E FD      243           jsr   crout
  320. 08B9:60            244           rts
  321. 08BA:              245 *
  322. 08BA:              246 *******************************************************
  323. 08BA:              247 *
  324. 08BA:        08BA  248 VisitDir  equ   *
  325. 08BA:              249 *
  326. 08BA:              250 * Print the name of the subdirectory we are looking
  327. 08BA:              251 * at, appending a "/" to it (to indicate that it's
  328. 08BA:              252 * a directory), and then calling RecursDir to list
  329. 08BA:              253 * everything in that directory.
  330. 08BA:              254 *
  331. 08BA:20 AC 09      255           jsr   PrintEntry    ; print dir's name
  332. 08BD:A9 AF         256           lda   #'/'|$80      ; tack on / at end
  333. 08BF:20 ED FD      257           jsr   cout
  334. 08C2:20 8E FD      258           jsr   crout
  335. 08C5:              259 *
  336. 08C5:20 C9 08      260           jsr   RecursDir     ; enumerate all entries in sub-dir.
  337. 08C8:              261 *
  338. 08C8:60            262           rts
  339. 08C9:              263 *
  340. 08C9:              264 *******************************************************
  341. 08C9:              265 *
  342. 08C9:        08C9  266 RecursDir equ   *
  343. 08C9:              267 *
  344. 08C9:              268 * This routine calls ReadDir recursively. It
  345. 08C9:              269 *
  346. 08C9:              270 * - increments the recursion depth counter,
  347. 08C9:              271 * - saves certain variables onto the stack
  348. 08C9:              272 * - closes the current directory
  349. 08C9:              273 * - creates the name of the new directory
  350. 08C9:              274 * - calls ReadDir (recursively)
  351. 08C9:              275 * - restores the variables from the stack
  352. 08C9:              276 * - restores directory name to original value
  353. 08C9:              277 * - re-opens the old directory
  354. 08C9:              278 * - moves to our last position within it
  355. 08C9:              279 * - decrements the recursion depth counter
  356. 08C9:              280 *
  357. 08C9:EE CE 09      281           inc   Depth         ; bump this for recursive call
  358. 08CC:              282 *
  359. 08CC:              283 * Save everything we can think of (the women,
  360. 08CC:              284 * the children, the beer, etc.).
  361. 08CC:              285 *
  362. 08CC:A5 83         286           lda   entPtr+1
  363. 08CE:48            287           pha
  364. 08CF:A5 82         288           lda   entPtr
  365. 08D1:48            289           pha
  366. 08D2:AD CF 09      290           lda   ThisBEntry
  367.  
  368. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 7
  369.  
  370. 08D5:48            291           pha
  371. 08D6:AD D0 09      292           lda   ThisBlock
  372. 08D9:48            293           pha
  373. 08DA:AD D1 09      294           lda   entryLen
  374. 08DD:48            295           pha
  375. 08DE:AD D2 09      296           lda   entPerblk
  376. 08E1:48            297           pha
  377. 08E2:              298 *
  378. 08E2:              299 * Close the current directory, as ReadDir will
  379. 08E2:              300 * open files of its own, and we don't want to 
  380. 08E2:              301 * have a bunch of open files lying around.
  381. 08E2:              302 *
  382. 08E2:20 00 BF      303           jsr   MLI
  383. 08E5:CC            304           db    mliClose
  384. 08E6:E1 09         305           dw    CloseParms
  385. 08E8:              306 *
  386. 08E8:20 2F 09      307           jsr   ExtendName    ; make new dir name
  387. 08EB:              308 *
  388. 08EB:20 29 08      309           jsr   ReadDir1      ; enumerate the subdirectory
  389. 08EE:              310 *
  390. 08EE:20 65 09      311           jsr   ChopName      ; restore old directory name
  391. 08F1:              312 *
  392. 08F1:20 79 08      313           jsr   OpenDir       ; re-open it back up
  393. 08F4:90 01   08F7  314           bcc   reOpened
  394. 08F6:              315 *
  395. 08F6:              316 * Can't continue from this point--exit in
  396. 08F6:              317 * whatever way is appropriate for your
  397. 08F6:              318 * program.
  398. 08F6:              319 *
  399. 08F6:00            320           brk
  400. 08F7:              321 *
  401. 08F7:        08F7  322 reOpened  equ   *
  402. 08F7:              323 *
  403. 08F7:              324 * Restore everything that we saved before
  404. 08F7:              325 *
  405. 08F7:68            326           pla
  406. 08F8:8D D2 09      327           sta   entPerBlk
  407. 08FB:68            328           pla
  408. 08FC:8D D1 09      329           sta   entryLen
  409. 08FF:68            330           pla
  410. 0900:8D D0 09      331           sta   ThisBlock
  411. 0903:68            332           pla
  412. 0904:8D CF 09      333           sta   ThisBEntry
  413. 0907:68            334           pla
  414. 0908:85 82         335           sta   entPtr
  415. 090A:68            336           pla
  416. 090B:85 83         337           sta   entPtr+1
  417. 090D:              338 *
  418. 090D:A9 00         339           lda   #0
  419. 090F:8D E5 09      340           sta   Mark
  420. 0912:8D E7 09      341           sta   Mark+2
  421. 0915:AD D0 09      342           lda   ThisBlock     ; reset last position in dir
  422. 0918:0A            343           asl   a             ; = to block # times 512
  423. 0919:8D E6 09      344           sta   Mark+1
  424. 091C:2E E7 09      345           rol   Mark+2
  425. 091F:              346 *
  426. 091F:20 00 BF      347           jsr   MLI           ; reset the file marker
  427. 0922:CE            348           db    mliSetMark
  428.  
  429. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 8
  430.  
  431. 0923:E3 09         349           dw    SetMParms
  432. 0925:              350 *
  433. 0925:20 00 BF      351           jsr   MLI           ; now read in the block we
  434. 0928:CA            352           db    mliRead       ; were on last.
  435. 0929:D9 09         353           dw    ReadParms
  436. 092B:              354 *
  437. 092B:CE CE 09      355           dec   Depth
  438. 092E:60            356           rts
  439. 092F:              357 *
  440. 092F:              358 *******************************************************
  441. 092F:              359 *
  442. 092F:        092F  360 ExtendName equ  *
  443. 092F:              361 *
  444. 092F:              362 * Append the name in the current directory entry
  445. 092F:              363 * to the name in the directory name buffer. This
  446. 092F:              364 * will allow us to descend another level into the
  447. 092F:              365 * disk hierarchy when we call ReadDir.
  448. 092F:              366 *
  449. 092F:A0 00         367           ldy   #0            ; get length of string to copy
  450. 0931:B1 82         368           lda   (entPtr),y    
  451. 0933:29 0F         369           and   #$0F
  452. 0935:8D 62 09      370           sta   extCnt        ; save the length here
  453. 0938:8C 63 09      371           sty   srcPtr        ; init src ptr to zero
  454. 093B:              372 *
  455. 093B:A0 00         373           ldy   #0            ; init dest ptr to end of
  456. 093D:B1 80         374           lda   (dirName),y   ; the current directory name
  457. 093F:8D 64 09      375           sta   destPtr
  458. 0942:              376 *
  459. 0942:        0942  377 extloop   equ   *
  460. 0942:EE 63 09      378           inc   srcPtr        ; bump to next char to read
  461. 0945:EE 64 09      379           inc   destPtr       ; bump to next empty location
  462. 0948:AC 63 09      380           ldy   srcPtr        ; get char of sub-dir name
  463. 094B:B1 82         381           lda   (entPtr),y
  464. 094D:AC 64 09      382           ldy   destPtr       ; tack on to end of cur. dir.
  465. 0950:91 80         383           sta   (dirName),y
  466. 0952:CE 62 09      384           dec   extCnt        ; done all chars?
  467. 0955:D0 EB   0942  385           bne   extloop       ; no - so do more
  468. 0957:              386 *
  469. 0957:C8            387           iny
  470. 0958:A9 2F         388           lda   #'/'          ; tack "/" on to the end
  471. 095A:91 80         389           sta   (dirName),y
  472. 095C:              390 *
  473. 095C:98            391           tya                 ; fix length of filename to open
  474. 095D:A0 00         392           ldy   #0
  475. 095F:91 80         393           sta   (dirName),y
  476. 0961:              394 *
  477. 0961:60            395           rts
  478. 0962:              396 *
  479. 0962:        0001  397 extCnt    ds    1
  480. 0963:        0001  398 srcPtr    ds    1
  481. 0964:        0001  399 destPtr   ds    1
  482. 0965:              400 *
  483. 0965:              401 *
  484. 0965:              402 *******************************************************
  485. 0965:              403 *
  486. 0965:        0965  404 ChopName  equ   *
  487. 0965:              405 *
  488. 0965:              406 * Scans the current directory name, and chops
  489.  
  490. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 9
  491.  
  492. 0965:              407 * off characters until it gets to a /.
  493. 0965:              408 *
  494. 0965:A0 00         409           ldy   #0            ; get len of current dir.
  495. 0967:B1 80         410           lda   (dirName),y
  496. 0969:A8            411           tay
  497. 096A:        096A  412 ChopLoop  equ   *
  498. 096A:88            413           dey                 ; bump to previous char
  499. 096B:B1 80         414           lda   (dirName),y
  500. 096D:C9 2F         415           cmp   #'/'
  501. 096F:D0 F9   096A  416           bne   ChopLoop
  502. 0971:98            417           tya
  503. 0972:A0 00         418           ldy   #0
  504. 0974:91 80         419           sta   (dirName),y
  505. 0976:60            420           rts
  506. 0977:              421 *
  507. 0977:              422 *******************************************************
  508. 0977:              423 *
  509. 0977:        0977  424 GetNext   equ   *
  510. 0977:              425 *
  511. 0977:              426 * This routine is responsible for making a pointer
  512. 0977:              427 * to the next entry in the directory. If there are
  513. 0977:              428 * still entries to be processed in this block, then
  514. 0977:              429 * we simply bump the pointer by the size of the
  515. 0977:              430 * directory entry. If we have finished with this
  516. 0977:              431 * block, then we read in the next block, point to
  517. 0977:              432 * the first entry, and increment our block counter.
  518. 0977:              433 *
  519. 0977:CE CF 09      434           dec   ThisBEntry    ; dec count for this block
  520. 097A:F0 10   098C  435           beq   ReadNext      ; done w/this block, get next one
  521. 097C:              436 *
  522. 097C:18            437           clc                 ; else bump up index
  523. 097D:A5 82         438           lda   entPtr
  524. 097F:6D D1 09      439           adc   entryLen
  525. 0982:85 82         440           sta   entPtr
  526. 0984:A5 83         441           lda   entPtr+1
  527. 0986:69 00         442           adc   #0
  528. 0988:85 83         443           sta   entPtr+1
  529. 098A:18            444           clc                 ; say that the buffer's good
  530. 098B:60            445           rts
  531. 098C:              446 *
  532. 098C:        098C  447 ReadNext  equ   *
  533. 098C:20 00 BF      448           jsr   MLI           ; get the next block
  534. 098F:CA            449           db    mliRead
  535. 0990:D9 09         450           dw    ReadParms
  536. 0992:B0 16   09AA  451           bcs   DirDone
  537. 0994:              452 *
  538. 0994:EE D0 09      453           inc   ThisBlock
  539. 0997:              454 *
  540. 0997:A9 EF         455           lda   #buffer+4     ; set entry pointer to beginning
  541. 0999:85 82         456           sta   entPtr        ; of first entry in block
  542. 099B:A9 09         457           lda   #<buffer+4
  543. 099D:85 83         458           sta   entPtr+1
  544. 099F:              459 *
  545. 099F:AD D2 09      460           lda   entPerBlk     ; re-init 'entries in this block'
  546. 09A2:8D CF 09      461           sta   ThisBEntry
  547. 09A5:CE CF 09      462           dec   ThisBEntry
  548. 09A8:18            463           clc                 ; return 'No error'
  549. 09A9:60            464           rts
  550.  
  551. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 10
  552.  
  553. 09AA:              465 *
  554. 09AA:        09AA  466 DirDone   equ   *
  555. 09AA:38            467           sec               ; return 'an error occurred' (error in A)
  556. 09AB:60            468           rts
  557. 09AC:              469 *
  558. 09AC:              470 *******************************************************
  559. 09AC:              471 *
  560. 09AC:        09AC  472 PrintEntry equ  *
  561. 09AC:              473 *
  562. 09AC:              474 * Using the pointer to the current entry, this 
  563. 09AC:              475 * routine prints the entry name. It also pays
  564. 09AC:              476 * attention to the recursion depth, and indents
  565. 09AC:              477 * by 2 spaces for every level.
  566. 09AC:              478 *
  567. 09AC:AD CE 09      479           lda   Depth         ; indent two blanks for each level
  568. 09AF:0A            480           asl   a             ; of directory nesting
  569. 09B0:AA            481           tax
  570. 09B1:F0 08   09BB  482           beq   spcDone
  571. 09B3:A9 A0         483 spcloop   lda   #space
  572. 09B5:20 ED FD      484           jsr   cout
  573. 09B8:CA            485           dex
  574. 09B9:D0 F8   09B3  486           bne   spcloop
  575. 09BB:        09BB  487 spcDone   equ   *
  576. 09BB:              488 *
  577. 09BB:A0 00         489           ldy   #0            ; get byte that has the length byte
  578. 09BD:B1 82         490           lda   (entPtr),y
  579. 09BF:29 0F         491           and   #$0F          ; get just the length
  580. 09C1:AA            492           tax
  581. 09C2:        09C2  493 PrntLoop  equ   *
  582. 09C2:C8            494           iny                 ; bump to the next char.
  583. 09C3:B1 82         495           lda   (entPtr),y    ; get next char
  584. 09C5:09 80         496           ora   #$80          ; COUT likes high bit set
  585. 09C7:20 ED FD      497           jsr   cout          ; print it
  586. 09CA:CA            498           dex                 ; printed all chars?
  587. 09CB:D0 F5   09C2  499           bne   PrntLoop      ; no - keep going
  588. 09CD:60            500           rts
  589. 09CE:              501 *
  590. 09CE:              502 *******************************************************
  591. 09CE:              503 *
  592. 09CE:              504 * Some global variables
  593. 09CE:              505 *
  594. 09CE:        0001  506 Depth     ds    1             ; amount of recursion
  595. 09CF:        0001  507 ThisBEntry ds   1             ; entry in this block
  596. 09D0:        0001  508 ThisBlock ds    1             ; block with dir
  597. 09D1:        0001  509 entryLen  ds    1             ; length of each directory entry
  598. 09D2:        0001  510 entPerBlk ds    1             ; entries per block
  599. 09D3:              511 *
  600. 09D3:              512 *******************************************************
  601. 09D3:              513 *
  602. 09D3:              514 * ProDOS command parameter blocks
  603. 09D3:              515 *
  604. 09D3:        09D3  516 OpenParms equ   *
  605. 09D3:03            517           db    3             ; number of parms
  606. 09D4:        0002  518 OpenName  ds    2             ; pointer to filename
  607. 09D6:00 00         519 ioBuf     dw    $0000         ; I/O buffer
  608. 09D8:        0001  520 oRefNum   ds    1             ; returned refnum
  609. 09D9:              521 *
  610. 09D9:        09D9  522 ReadParms equ   *
  611.  
  612. 01 CATALOG         ProDOS Catalog Routine              14-OCT-89  16:20 PAGE 11
  613.  
  614. 09D9:04            523           db    4             ; number of parms
  615. 09DA:        0001  524 rRefNum   ds    1             ; refnum from Open
  616. 09DB:EB 09         525           dw    buffer        ; pointer to buffer
  617. 09DD:00 02         526 reqAmt    dw    512           ; amount to read
  618. 09DF:        0002  527 retAmt    ds    2             ; amount actually read
  619. 09E1:              528 *
  620. 09E1:        09E1  529 CloseParms equ  *
  621. 09E1:01            530           db    1             ; number of parms
  622. 09E2:        0001  531 cRefNum   ds    1             ; refnum from Open
  623. 09E3:              532 *
  624. 09E3:        09E3  533 SetMParms equ   *
  625. 09E3:02            534           db    2             ; number of parms
  626. 09E4:        0001  535 sRefNum   ds    1             ; refnum from Open
  627. 09E5:        0003  536 Mark      ds    3             ; file position
  628. 09E8:              537 *
  629. 09E8:        09E8  538 GetPParms equ   *
  630. 09E8:01            539           db    1             ; number of parms
  631. 09E9:EB 0B         540           dw    nameBuffer    ; pointer to buffer
  632. 09EB:              541 *
  633. 09EB:        0200  542 buffer    ds    512           ; enough for whole block
  634. 0BEB:              543 *
  635. 0BEB:        0040  544 nameBuffer ds   64            ; space for directory name
  636.  
  637. 01 SYMBOL TABLE    SORTED BY SYMBOL                    14-OCT-89  16:20 PAGE 12
  638.  
  639.  09EB BUFFER         096A CHOPLOOP       0965 CHOPNAME       09E1 CLOSEPARMS    
  640.  FDED COUT           09E2 CREFNUM        FD8E CROUT          09CE DEPTH         
  641.  0964 DESTPTR        09AA DIRDONE          80 DIRNAME        084D DONE          
  642.    4C ENDOFFILE      09D2 ENTPERBLK        82 ENTPTR         09D1 ENTRYLEN      
  643.  081E EXIT           0962 EXTCNT         092F EXTENDNAME     0942 EXTLOOP       
  644.  BEF5 GETBUFR        0977 GETNEXT        09E8 GETPPARMS      0878 HITDIREND     
  645.  09D6 IOBUF          0845 ITSADIR        0831 LOOP           09E5 MARK          
  646.    CC MLICLOSE         C7 MLIGETPFX        C8 MLIOPEN        BF00 MLI           
  647.    CA MLIREAD          CE MLISETMARK     0BEB NAMEBUFFER     0848 NEXTENTRY     
  648.    24 OENTBLK          23 OENTLEN        0879 OPENDIR        08B2 OPENDONE      
  649.  09D4 OPENNAME       09D3 OPENPARMS      09D8 OREFNUM          00 OTYPE         
  650.  FDDA PRBYTE         09AC PRINTENTRY     09C2 PRNTLOOP       0829 READDIR1      
  651.  081F READDIR        098C READNEXT       09D9 READPARMS      08C9 RECURSDIR     
  652.  08F7 REOPENED      ?09DD REQAMT        ?09DF RETAMT         09DA RREFNUM       
  653.  09E3 SETMPARMS        A0 SPACE          09BB SPCDONE        09B3 SPCLOOP       
  654.  0963 SRCPTR         09E4 SREFNUM       ?0800 START          09CF THISBENTRY    
  655.  09D0 THISBLOCK      08BA VISITDIR       08B3 VISITFILE     
  656. ** SUCCESSFUL ASSEMBLY := NO ERRORS
  657. ** ASSEMBLER CREATED ON 15-JAN-84 21:28 
  658. ** TOTAL LINES ASSEMBLED   544 
  659. ** FREE SPACE PAGE COUNT   81 
  660.  
  661.  
  662. Further Reference
  663. _____________________________________________________________________________
  664.     o    ProDOS 8 Technical Reference Manual
  665.     o    AppleShare Programmer's Guide to the Apple IIGS
  666.